/*
 * VueHall.java Created on Oct 19, 2006 by M.C.Boulahiya
 */

import hall.*;

import java.io.*;
import java.util.ArrayList;

import javax.media.j3d.*;
import javax.vecmath.*;

import com.sun.j3d.utils.geometry.Sphere;

/**
 * @author M.C.Boulahiya
 * 
 * Contient toutes les informations vues par un troll.
 */
public class VueHall {
	private Point3f position;
	private Point2i distancesVue; 
	private Point2i limitationsVue;
	private BranchGroup hallBG;
	private ArrayList<Monstre> monstres;
	private BranchGroup monstresBG;
	private ArrayList<Troll> trolls;
	private BranchGroup trollsBG;
	private ArrayList<Tresor> tresors;
	private BranchGroup tresorsBG;
	private ArrayList<Champignon> champignons;
	private BranchGroup champignonsBG;
	private ArrayList<Lieu> lieux;
	private BranchGroup lieuxBG;
  
	/**
	 * Le constructeur par defaut.
	 */
	public VueHall() {
		this.position = new Point3f();
		this.distancesVue = new Point2i();
		this.limitationsVue = new Point2i();
		this.monstres = new ArrayList<Monstre>();
		this.trolls = new ArrayList<Troll>();
		this.tresors = new ArrayList<Tresor>();
		this.champignons = new ArrayList<Champignon>();
		this.lieux = new ArrayList<Lieu>();
	} // Fin de VueHall
	
	
	/**
	 * Lit le fichier filename, et en extrait les donnees.
	 *  
	 * @param filename Le nom du fichier de vue.
	 */
	public void extractionFromView(String filename) {
		RandomAccessFile infile = null;
		try {
			infile = new RandomAccessFile(filename,"r");
		} catch (FileNotFoundException exception) {
			exception.printStackTrace();
		}

		if (infile != null) {
      traiter(infile);
      
      try {
				infile.close();
			} catch (IOException exception) {
				exception.printStackTrace();
			}
		}
	
	} // Fin de ExtractionFromView(String)
	
	
	/**
	 * Extrait les donnees contenues dans le fichier infile.
	 * 
	 * @param infile Le fichier contenant la vue.
	 */
	private void traiter(RandomAccessFile infile) {
		String line = null;
		
    try {
			infile.seek(0);
		} catch (IOException exception) {
			exception.printStackTrace();
		}
		
		while (true) {
			try {
				line = Constantes.myReadLine(infile);
			} catch (IOException exception) {
				exception.printStackTrace();
			}
			if (line.length() != 0) {
				if (line.contains("* Ma Position")) {
					// Extraire les coordonnees de la case centrale de la vue
					Constantes.start = 0;
					position.y = Constantes.extraireInt(line);
					position.x = Constantes.extraireInt(line);
					position.z = Constantes.extraireInt(line);
//					System.out.println("Position : "+p);
				}
				if (line.contains("* Ma Vue")) {
					// Extraire les limitaions de la vue
					Constantes.start = 0;
					distancesVue.x = Constantes.extraireInt(line);
					distancesVue.y = Constantes.extraireInt(line);
//					System.out.println("vue : "+distancesVue);
				}
				if (line.contains("* L'affichage")) {
					// Extraire les limitaions de l'affichage
					Constantes.start = 0;
					limitationsVue.x = Constantes.extraireInt(line);
					limitationsVue.y = Constantes.extraireInt(line);
//					System.out.println("affichage : "+limitationsVue);
				}
				if (line.startsWith("MONSTRES ERRANTS")) {
					// Extraire les coordonnees des monstres
					int nbMonstres = 0;
					try {
						line = Constantes.myReadLine(infile); //Dist. Ref. Niveau Nom X Y N
						line = Constantes.myReadLine(infile); 
						while (!line.startsWith("TROLLS")) {
							// Creation d'un objet monstre
							Monstre m = new Monstre();
							m.initialiser(line);
							monstres.add(m);
							nbMonstres++;
							
							line = Constantes.myReadLine(infile);
						}
						
					} catch (IOException exception) {
						exception.printStackTrace();
					}
					
//					System.out.println("monstres "+nbMonstres);
//					System.out.println(monstres);
				}
				if (line.startsWith("TROLLS")) {
					// Extraire les coordonnees des trolls
					int nbTrolls = 0;
					try {
						line = Constantes.myReadLine(infile);
						//Dist. Ref. Nom Niveau Race Guilde X Y N
						//Dist.	Ref. Nom Niveau	Race Guilde PV DLA X Y N
						line = Constantes.myReadLine(infile);
						
						int x = 0;
						for (int i = 0; i < line.length(); i++)
							if (line.charAt(i) == '\t')
								x++;
						if (x == 8) {						
							while (!line.startsWith("TRESORS")) {
								// Creation d'un objet troll
								Troll t = new Troll();
								t.initialiser(line);
								trolls.add(t);
								nbTrolls++;

								line = Constantes.myReadLine(infile);
							}
						} else {
							while (!line.startsWith("TR")) {
								x = 0;
								for (int i = 0; i < line.length(); i++)
									if (line.charAt(i) == '\t')
										x++;

								// Creation d'un objet troll
								Troll t = new Troll();
								if (x < 10) {
									String fin = Constantes.myReadLine(infile);
									t.initialiserPlusBis(line);
									t.initialiserPlusTer(fin);

								} else {
									t.initialiserPlus(line);
								}
								trolls.add(t);
								nbTrolls++;
								
								line = Constantes.myReadLine(infile);
							}
						}
						
					} catch (IOException exception) {
						exception.printStackTrace();
					}
					
//					System.out.println("trolls "+nbTrolls);
//					System.out.println(trolls);
				}
				if ((line.startsWith("TR")) && (line.contains("SORS"))) {
					// Extraire les coordonnees des tresors
					int nbTresors = 0;
					try {
						line = Constantes.myReadLine(infile); //Dist.	Ref.	Type	X	Y	N
						line = Constantes.myReadLine(infile); 
						while (!line.startsWith("CHAMPIGNONS")) {
							// Creation d'un objet tresor
							Tresor t = new Tresor();
							t.initialiser(line);
							tresors.add(t);
							nbTresors++;
							
							line = Constantes.myReadLine(infile);
						}
						
					} catch (IOException exception) {
						exception.printStackTrace();
					}
					
//					System.out.println("tresors "+nbTresors);
//					System.out.println(tresors);
				}
				if (line.startsWith("CHAMPIGNONS")) {
					// Extraire les coordonnees des champignons
					int nbChampis = 0;
					try {
						line = Constantes.myReadLine(infile); //Dist.	Ref.	-	X	Y	N
						line = Constantes.myReadLine(infile); 
						while (!line.startsWith("LIEUX")) {
							// Creation d'un objet champi
							Champignon c = new Champignon();
							c.initialiser(line);
							champignons.add(c);
							nbChampis++;
							
							line = Constantes.myReadLine(infile);
						}
						
					} catch (IOException exception) {
						exception.printStackTrace();
					}
					
//					System.out.println("champignons "+nbChampis);
//					System.out.println(champignons);
				}
				if (line.startsWith("LIEUX")) {
					// Extraire les coordonnees des lieux
					int nbLieux = 0;
					try {
						line = Constantes.myReadLine(infile); //Dist.	Ref.	Nom	X	Y	N
						line = Constantes.myReadLine(infile); 
						while (!line.startsWith("[Contact : dm@mountyhall.com]")) {
							// Creation d'un objet lieu
							Lieu l = new Lieu();
							l.initialiser(line);
							lieux.add(l);
							nbLieux++;
							
							line = Constantes.myReadLine(infile);
						}
						
					} catch (IOException exception) {
						exception.printStackTrace();
					}
					
//					System.out.println("lieux "+nbLieux);
//					System.out.println(lieux);
				}
				if (line.startsWith("[Contact : dm@mountyhall.com]")) {
//					System.out.println("C'est fini!");
					break;
				} 
			}
		}
	} // Fin de traiter(RandomAccessFile)


	/**
	 * @return Les hallBG.
	 */
	public BranchGroup getHallBG() {
		if (hallBG == null)
			createHall();
		return hallBG;
	} // Fin de getLieuxBG


	/**
	 * @return Les trollsBG.
	 */
	public BranchGroup getTrollsBG() {
		if (trollsBG == null)
			afficheTrolls();
		return trollsBG;
	} // Fin de getTrollsBG


	/**
	 * @return Les monstresBG.
	 */
	public BranchGroup getMonstresBG() {
		return monstresBG;
	} // Fin de getMonstresBG


	/**
	 * @return Les tresorsBG.
	 */
	public BranchGroup getTresorsBG() {
		return tresorsBG;
	} // Fin de getTresorsBG
  
  
	/**
	 * @return Les champignonsBG.
	 */
	public BranchGroup getChampignonsBG() {
		return champignonsBG;
	} // Fin de getChampignonsBG

	
	/**
	 * @return Les lieuxBG.
	 */
	public BranchGroup getLieuxBG() {
		return lieuxBG;
	} // Fin de getLieuxBG

	
	/**
	 * Construit le cadrillage des cases du Hall.
	 * 
	 * @return Le hall.
	 */
	private void createHall() {
		int horiz = limitationsVue.x, 
				verti = limitationsVue.y;
		float maxXZ = horiz*Constantes.longueur + Constantes.longueur/2,
					maxY  = verti*Constantes.longueur + Constantes.longueur/2;
		hallBG = new BranchGroup();
		hallBG.setName("hallBG");
	  		  
		// cadrillage horizontaux
		// 2 points pour les lignes x et 2 pour les lignes z 
		int nbLignesH = horiz * 2 + 2,
				nbLignesV = verti * 2 + 2,
				nbLignes = 2 * 2 * nbLignesH * nbLignesV;
		LineArray horizontalGeom = new LineArray(nbLignes, LineArray.COORDINATES);
	  
	  int counter = 0;
	  float niv = -maxY;
	  for (int i = 0; i < nbLignesV; i++) {
	  	float x = -maxXZ, z = -maxXZ;
	  	for (int j = 0; j < nbLignesH; j++) {
	  		horizontalGeom.setCoordinate( counter++, new Point3f( -maxXZ, niv, z));
	  		horizontalGeom.setCoordinate( counter++, new Point3f(  maxXZ, niv, z));
	  		horizontalGeom.setCoordinate( counter++, new Point3f( x, niv, -maxXZ));
	  		horizontalGeom.setCoordinate( counter++, new Point3f( x, niv,  maxXZ));
	  		x += Constantes.longueur;
	  		z += Constantes.longueur;
	  	}
	  	niv += Constantes.longueur;
	  }
	  	  
		// cadrillages verticaux
	  nbLignes = 2 * nbLignesH * nbLignesH;
	  LineArray verticalGeom = new LineArray(nbLignes, LineArray.COORDINATES);
	  counter = 0;
	  niv = -maxXZ;
	  for (int i = 0; i < nbLignesH; i++) {
	  	float x = -maxXZ, y = -maxY;
	  	for (int j = 0; j < nbLignesH; j++) {
	  		verticalGeom.setCoordinate( counter++, new Point3f( x, -maxY, niv));
	  		verticalGeom.setCoordinate( counter++, new Point3f( x,  maxY, niv));
	  		x += Constantes.longueur;
	  		y += Constantes.longueur;
	  	}
	  	niv += Constantes.longueur;
	  }
	  
	  ColoringAttributes blueColoringAttribute = new ColoringAttributes();
	  blueColoringAttribute.setColor(new Color3f(0.1f,0.1f,0.8f));
	  Appearance blueAppearance = new Appearance();
		blueAppearance.setColoringAttributes(blueColoringAttribute);
		Sphere centreCadrillage = new Sphere(0.08f, blueAppearance );
	  centreCadrillage.setName("centreCadillage@not");
	  ((Shape3D)centreCadrillage.getShape()).setName("ShapeDeCentreCadillage@not");

	  hallBG.addChild(centreCadrillage);

	  PolygonAttributes polygonAttributes = new PolygonAttributes();
	  polygonAttributes.setCullFace(PolygonAttributes.CULL_NONE);
	  ColoringAttributes greenColoringAttributes = new ColoringAttributes();
	  greenColoringAttributes.setCapability(ColoringAttributes.ALLOW_COLOR_WRITE);
	  greenColoringAttributes.setColor(new Color3f(0.1f, 0.8f, 0.1f));
	  LineAttributes lineAttributes = new LineAttributes();
	  lineAttributes.setLineWidth(1.0f);
	  Appearance greenAppearance = new Appearance();
	  greenAppearance.setColoringAttributes(greenColoringAttributes);
	  greenAppearance.setLineAttributes(lineAttributes);
	  greenAppearance.setPolygonAttributes(polygonAttributes);
	  
	  Shape3D horizontalCadrillage = new Shape3D(horizontalGeom, greenAppearance);
	  horizontalCadrillage.setName("horizontalCadrillage@not");
	  hallBG.addChild(horizontalCadrillage);
	  
	  Shape3D verticalCadrillage = new Shape3D(verticalGeom, greenAppearance);
	  verticalCadrillage.setName("verticalCadrillage@not");
	  hallBG.addChild(verticalCadrillage);
	} // Fin de createHall(float)
  
	
	/**
	 * 
	 */
	private void afficheTrolls() {
		trollsBG = new BranchGroup();
		for (int i = 0; i < trolls.size(); i++) {
			Troll t = trolls.get(i);
			Point3f trollPosition = t.getPosition();
			
			Vector3f v3f = new Vector3f();
			v3f.sub(trollPosition, position);
			v3f.scale(Constantes.longueur);
			System.out.println(v3f);
			Transform3D t3d = new Transform3D();
			t3d.setTranslation(v3f);
			TransformGroup unTrollTG = new TransformGroup(t3d);
			trollsBG.addChild(unTrollTG);
			
		  ColoringAttributes whiteColoringAttribute = new ColoringAttributes();
		  whiteColoringAttribute.setColor(new Color3f(1.f,1.f,1.f));
		  Appearance whiteAppearance = new Appearance();
			whiteAppearance.setColoringAttributes(whiteColoringAttribute);
			Sphere unTroll = new Sphere(0.08f, whiteAppearance );
		  unTroll.setName("un Troll");
		  ((Shape3D)unTroll.getShape()).setName("ShapeDeUnTroll");

		  unTrollTG.addChild(unTroll);
		}
		
	} // Fin de afficheTrolls
	
} // Fin de la classe VueHall

// Fin du fichier VueHall.java